package zip;

import Util.CreateFileUtil;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Param;

import java.io.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * JDK GZIP test
 */
public class GZipTest extends TestParent {
    @Param({"1", "2", "3", "4", "5", "6", "7", "8", "9"})
    public int LEVEL;
    static HashMap<Integer, byte[]> compressFile;
    static HashMap<Integer, byte[]> deCompressFile;
    static {
        compressFile = new HashMap<>();
        deCompressFile = new HashMap<>();
        for (int i = 1; i < 10; i++) {
            compressFile.put(i, CreateFileUtil.getBytesByFile("./test/test_"+i+".json"));
            deCompressFile.put(i,CreateFileUtil.getBytesByFile("./test/test_"+i+".gzip"));
        }
    }

    @Benchmark
    public byte[] compress() {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        GZIPOutputStream gzip;
        try {
            gzip = new GZIPOutputStream(os);
            gzip.write(compressFile.get(LEVEL));
            gzip.close();
        } catch ( Exception e) {
            e.printStackTrace();
        }
        byte[] out = Base64.getEncoder().encode(os.toByteArray());
        CreateFileUtil.bytes2File(out,"./test/","test_"+LEVEL+".gzip");
        return out;
    }

    @Benchmark
    public byte[] deCompress() {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(Base64.getDecoder().decode(deCompressFile.get(LEVEL)));
        try {
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                os.write(buffer, 0, n);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        byte[] out = os.toByteArray();
        CreateFileUtil.bytes2File(out,"./test/","test_"+LEVEL+".gzip.json");
        return out;
    }
}
